﻿using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using RuoVea.ExConfig;
using RuoVea.ExFilter;
using RuoVea.OmiSystem.Language;
using RuoVea.OmiSystem.Options;
using RuoVea.OmiUI;
using SqlSugar;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using omiApp = RuoVea.OmiApi.SystemApp;

namespace RuoVea.OmiSystem
{
    /// <summary>
    /// 注入扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 字典管理接口
        /// </summary>
        /// <param name="services"></param>
        /// <param name="serviceLifetime"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiSystemSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            services.Configure<AppConfig>(AppSettings.Configuration);
            return DI(services, null, serviceLifetime);
        }

        /// <summary>
        /// 字典管理接口
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiSystemSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure<AppConfig>(config);
            AppConfig appConfig = services.BuildServiceProvider().GetRequiredService<IOptions<AppConfig>>()?.Value;
            return DI(services, appConfig, serviceLifetime);
        }

        /// <summary>
        /// 字典管理接口
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiSystemSetup(this IServiceCollection services, Action<AppConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure(config);
            AppConfig appConfig = services.BuildServiceProvider().GetRequiredService<IOptions<AppConfig>>()?.Value;
            return DI(services, appConfig, serviceLifetime);
        }

        #region DI
        private static IServiceCollection DI(IServiceCollection services, AppConfig appConfig, ServiceLifetime serviceLifetime)
        {
            if (appConfig == null && !string.IsNullOrWhiteSpace(appConfig?.PrefixRoute))
                if (!appConfig.PrefixRoute.StartsWith('/'))
                    throw new ArgumentNullException(i18n.prefixroute);
            ConfigManages.Config = appConfig;
            services.AddControllers().AddJsonOptions(o => { o.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); /*返回中文字符不转译*/ });
            services.AddRestfulModelsSetup();
            omiApp.ServiceCollectionExtensions.AddOmiSystemSetup(services, serviceLifetime);

            services.AddControllersWithViews().AddRazorRuntimeCompilation(option =>
            {
                option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.OrganizationController).GetTypeInfo().Assembly));
                option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.PositionController).GetTypeInfo().Assembly));
                option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.RoleController).GetTypeInfo().Assembly));
                option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.UserController).GetTypeInfo().Assembly));
                option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.MenuController).GetTypeInfo().Assembly));
            });
            return services;
        }
        #endregion

        /// <summary>
        /// 初始化数据库/初始化种子数据
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddSystemInitSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            omiApp.ServiceCollectionExtensions.AddSystemInitSetup(services,true);
            return services;
        }

        /// <summary>
        /// 字典管理页面UI
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseOmiSystemUI(this IApplicationBuilder app)
        {
            app.UseOmiUIStaticAssets();
            app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.OrganizationController).GetTypeInfo().Assembly) });
            app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.PositionController).GetTypeInfo().Assembly) });
            app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.RoleController).GetTypeInfo().Assembly) });
            app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.UserController).GetTypeInfo().Assembly) });
            app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.MenuController).GetTypeInfo().Assembly) });
            return app;
        }
    }
}
